
<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
        <meta name="description" content="Documentation for the GDBFrontend debugger">
      
      
      
      <link rel="icon" href="../../media/gdbfrontend-icon.png">
      <meta name="generator" content="mkdocs-1.2.3, mkdocs-material-8.1.9">
    
    
      
        <title>How to develop GDBFrontend plugins - GDBFrontend Documentation</title>
      
    
    
      <link rel="stylesheet" href="../../assets/stylesheets/main.2b4465f4.min.css">
      
        
        <link rel="stylesheet" href="../../assets/stylesheets/palette.e6a45f82.min.css">
        
      
    
    
    
      
        
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
        <style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
      
    
    
    <script>__md_scope=new URL("../..",location),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
    
      
  


  
  


  <script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-03F7PQRZ76"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){this.value&&gtag("event","search",{search_term:this.value})}),"undefined"!=typeof location$&&location$.subscribe(function(e){gtag("config","G-03F7PQRZ76",{page_path:e.pathname})})})</script>
  <script async src="https://www.googletagmanager.com/gtag/js?id=G-03F7PQRZ76"></script>


    
    
  </head>
  
  
    
    
      
    
    
    
    
    <body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="" data-md-color-accent="">
  
    
    
      <script>var palette=__md_get("__palette");if(palette&&"object"==typeof palette.color)for(var key of Object.keys(palette.color))document.body.setAttribute("data-md-color-"+key,palette.color[key])</script>
    
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#how-to-develop-gdbfrontend-plugins" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header__inner md-grid" aria-label="Header">
    <a href="https://github.com/rohanrhu/gdb-frontend" title="GDBFrontend Documentation" class="md-header__button md-logo" aria-label="GDBFrontend Documentation" data-md-component="logo">
      
  <img src="../../media/gdbfrontend-logo.png" alt="logo">

    </a>
    <label class="md-header__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header__title" data-md-component="header-title">
      <div class="md-header__ellipsis">
        <div class="md-header__topic">
          <span class="md-ellipsis">
            GDBFrontend Documentation
          </span>
        </div>
        <div class="md-header__topic" data-md-component="header-topic">
          <span class="md-ellipsis">
            
              How to develop GDBFrontend plugins
            
          </span>
        </div>
      </div>
    </div>
    
      <form class="md-header__option" data-md-component="palette">
        
          
          
          <input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="" data-md-color-accent=""  aria-label="Switch to dark mode"  type="radio" name="__palette" id="__palette_1">
          
            <label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 1 7 7c0 2.38-1.19 4.47-3 5.74V17a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2.26C6.19 13.47 5 11.38 5 9a7 7 0 0 1 7-7M9 21v-1h6v1a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1m3-17a5 5 0 0 0-5 5c0 2.05 1.23 3.81 3 4.58V16h4v-2.42c1.77-.77 3-2.53 3-4.58a5 5 0 0 0-5-5z"/></svg>
            </label>
          
        
          
          
          <input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="" data-md-color-accent=""  aria-label="Switch to light mode"  type="radio" name="__palette" id="__palette_2">
          
            <label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 0-7 7c0 2.38 1.19 4.47 3 5.74V17a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-2.26c1.81-1.27 3-3.36 3-5.74a7 7 0 0 0-7-7M9 21a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-1H9v1z"/></svg>
            </label>
          
        
      </form>
    
    
    
      <label class="md-header__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      <div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <nav class="md-search__options" aria-label="Search">
        
        <button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
        </button>
      </nav>
      
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
      <div class="md-header__source">
        <a href="https://github.com/rohanrhu/gdb-frontend/" title="Go to repository" class="md-source" data-md-component="source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    Github
  </div>
</a>
      </div>
    
  </nav>
  
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
          
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              
              <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    


<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href="https://github.com/rohanrhu/gdb-frontend" title="GDBFrontend Documentation" class="md-nav__button md-logo" aria-label="GDBFrontend Documentation" data-md-component="logo">
      
  <img src="../../media/gdbfrontend-logo.png" alt="logo">

    </a>
    GDBFrontend Documentation
  </label>
  
    <div class="md-nav__source">
      <a href="https://github.com/rohanrhu/gdb-frontend/" title="Go to repository" class="md-source" data-md-component="source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    Github
  </div>
</a>
    </div>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      

  
  
  
    <li class="md-nav__item">
      <a href="../.." class="md-nav__link">
        GDBFrontend README
      </a>
    </li>
  

    
      
      
      

  
  
    
  
  
    
    <li class="md-nav__item md-nav__item--active md-nav__item--nested">
      
      
        <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2" type="checkbox" id="__nav_2" checked>
      
      
      
      
        <label class="md-nav__link" for="__nav_2">
          Tutorials
          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <nav class="md-nav" aria-label="Tutorials" data-md-level="1">
        <label class="md-nav__title" for="__nav_2">
          <span class="md-nav__icon md-icon"></span>
          Tutorials
        </label>
        <ul class="md-nav__list" data-md-scrollfix>
          
            
              
  
  
  
    <li class="md-nav__item">
      <a href="../embedded-debugging/" class="md-nav__link">
        Embedded Debugging with GDBFrontend
      </a>
    </li>
  

            
          
            
              
  
  
  
    <li class="md-nav__item">
      <a href="../makefile-integration/" class="md-nav__link">
        How to integrate GDBFrontend with your Makefile?
      </a>
    </li>
  

            
          
            
              
  
  
    
  
  
    <li class="md-nav__item md-nav__item--active">
      
      <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
      
      
        
      
      
        <label class="md-nav__link md-nav__link--active" for="__toc">
          How to develop GDBFrontend plugins
          <span class="md-nav__icon md-icon"></span>
        </label>
      
      <a href="./" class="md-nav__link md-nav__link--active">
        How to develop GDBFrontend plugins
      </a>
      
        

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#example-plugin" class="md-nav__link">
    Example Plugin
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-fs-structure" class="md-nav__link">
    Plugin FS Structure
  </a>
  
    <nav class="md-nav" aria-label="Plugin FS Structure">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#plugin-name-format" class="md-nav__link">
    Plugin Name Format
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#enablingdisabling-a-plugin" class="md-nav__link">
    Enabling/Disabling a Plugin
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-load-order" class="md-nav__link">
    Plugin Load Order
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-files" class="md-nav__link">
    Plugin Files
  </a>
  
    <nav class="md-nav" aria-label="Plugin Files">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#configpy" class="md-nav__link">
    config.py
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#hellopy" class="md-nav__link">
    hello.py
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#urlspy" class="md-nav__link">
    urls.py
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#rest-api-modules" class="md-nav__link">
    Rest API Modules
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-objects" class="md-nav__link">
    Plugin Objects
  </a>
  
    <nav class="md-nav" aria-label="Plugin Objects">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#plugin-object-attributes" class="md-nav__link">
    Plugin Object Attributes
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#frontend" class="md-nav__link">
    Frontend
  </a>
  
    <nav class="md-nav" aria-label="Frontend">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#gdbfrontend-namespace" class="md-nav__link">
    GDBFrontend Namespace
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#backend-configuration" class="md-nav__link">
    Backend Configuration
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#frontend-components" class="md-nav__link">
    Frontend Components
  </a>
  
    <nav class="md-nav" aria-label="Frontend Components">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#root-components" class="md-nav__link">
    Root Components
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#sub-components" class="md-nav__link">
    Sub Components
  </a>
  
    <nav class="md-nav" aria-label="Sub Components">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#component-gdbfrontend" class="md-nav__link">
    Component: gdbFrontend
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
    </ul>
  
</nav>
      
    </li>
  

            
          
            
              
  
  
  
    <li class="md-nav__item">
      <a href="../python-c-extension-debugging/" class="md-nav__link">
        How to debug a Python C extension with GDBFrontend
      </a>
    </li>
  

            
          
        </ul>
      </nav>
    </li>
  

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              
              <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#example-plugin" class="md-nav__link">
    Example Plugin
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-fs-structure" class="md-nav__link">
    Plugin FS Structure
  </a>
  
    <nav class="md-nav" aria-label="Plugin FS Structure">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#plugin-name-format" class="md-nav__link">
    Plugin Name Format
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#enablingdisabling-a-plugin" class="md-nav__link">
    Enabling/Disabling a Plugin
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-load-order" class="md-nav__link">
    Plugin Load Order
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-files" class="md-nav__link">
    Plugin Files
  </a>
  
    <nav class="md-nav" aria-label="Plugin Files">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#configpy" class="md-nav__link">
    config.py
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#hellopy" class="md-nav__link">
    hello.py
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#urlspy" class="md-nav__link">
    urls.py
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#rest-api-modules" class="md-nav__link">
    Rest API Modules
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#plugin-objects" class="md-nav__link">
    Plugin Objects
  </a>
  
    <nav class="md-nav" aria-label="Plugin Objects">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#plugin-object-attributes" class="md-nav__link">
    Plugin Object Attributes
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#frontend" class="md-nav__link">
    Frontend
  </a>
  
    <nav class="md-nav" aria-label="Frontend">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#gdbfrontend-namespace" class="md-nav__link">
    GDBFrontend Namespace
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#backend-configuration" class="md-nav__link">
    Backend Configuration
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
        <li class="md-nav__item">
  <a href="#frontend-components" class="md-nav__link">
    Frontend Components
  </a>
  
    <nav class="md-nav" aria-label="Frontend Components">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#root-components" class="md-nav__link">
    Root Components
  </a>
  
</li>
        
          <li class="md-nav__item">
  <a href="#sub-components" class="md-nav__link">
    Sub Components
  </a>
  
    <nav class="md-nav" aria-label="Sub Components">
      <ul class="md-nav__list">
        
          <li class="md-nav__item">
  <a href="#component-gdbfrontend" class="md-nav__link">
    Component: gdbFrontend
  </a>
  
</li>
        
      </ul>
    </nav>
  
</li>
        
      </ul>
    </nav>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          <div class="md-content" data-md-component="content">
            <article class="md-content__inner md-typeset">
              
                
<a href="https://github.com/rohanrhu/gdb-frontend/edit/master/documentation/src/tutorials/plugin-development.md" title="Edit this page" class="md-content__button md-icon">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
</a>


<h1 id="how-to-develop-gdbfrontend-plugins">How to develop GDBFrontend plugins</h1>
<p>GDBFrontend supports plugins. Plugin development includes a few simple steps. You can develop plugins easily with following the instructions.</p>
<h2 id="example-plugin">Example Plugin</h2>
<p>There is an example plugin (<code>hello</code>) in <code>plugins/hello</code>.</p>
<p>Enable it before start the tutorial: Go to <code>config.py</code> and comment the line <code>"hello"</code>:
<div class="highlight"><pre><span></span><code><span class="n">disabled_plugins</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">&quot;hello&quot;</span>
<span class="p">]</span>
</code></pre></div></p>
<h2 id="plugin-fs-structure">Plugin FS Structure</h2>
<p>GDBFrontend plugins are stored in <code>plugins/</code> directory in the GDBFrontend root.</p>
<p>A typical plugin files look like this:
<div class="highlight"><pre><span></span><code>plugins/
   hello/
       frontend/
           html/
               hello.html
           js/
               hello.js
           css/
               hello.css
       url_modules/
           api.py
       config.py
       urls.py
       hello.py
</code></pre></div>
Plugins those are inside plugins directory will be loaded automatically.</p>
<h3 id="plugin-name-format">Plugin Name Format</h3>
<ul>
<li>On File System: <code>hello</code> (<code>hello/</code> directory, <code>hello.py</code>)</li>
<li>Plugin Backend Class: <code>HelloPlugin</code></li>
</ul>
<h2 id="enablingdisabling-a-plugin">Enabling/Disabling a Plugin</h2>
<p>You can disable a plugin with adding plugin name to <code>config.disabled_plugins</code>.</p>
<h2 id="plugin-load-order">Plugin Load Order</h2>
<p>You can specify plugin load order with <code>config.plugin_order</code>. Plugins from <code>config.plugin_order</code> will be loaded in order, after that the rest will be loaded.</p>
<h2 id="plugin-files">Plugin Files</h2>
<h3 id="configpy">config.py</h3>
<p>Includes basic information about your plugin.</p>
<div class="highlight"><pre><span></span><code><span class="n">DESCRIPTION</span> <span class="o">=</span> <span class="s2">&quot;Example GDBFrontend plugin.&quot;</span>
<span class="n">AUTHOR</span> <span class="o">=</span> <span class="s2">&quot;Oğuzhan Eroğlu &lt;rohanrhu2@gmail.com&gt; (https://oguzhaneroglu.com/)&quot;</span>
<span class="n">HOMEPAGE</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/rohanrhu/gdb-frontend&quot;</span>
<span class="n">VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
</code></pre></div>
<h3 id="hellopy">hello.py</h3>
<p>Plugin backend file must be named as <code>[plugin name].py</code> and plugin class must be named as <code>[plugin name]Plugin</code> and intherits <code>plugin.GDBFrontendPlugin</code>.</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">importlib</span>

<span class="kn">import</span> <span class="nn">plugin</span>

<span class="n">gdb</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">import_module</span><span class="p">(</span><span class="s2">&quot;gdb&quot;</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">HelloPlugin</span><span class="p">(</span><span class="n">plugin</span><span class="o">.</span><span class="n">GDBFrontendPlugin</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">plugin</span><span class="o">.</span><span class="n">GDBFrontendPlugin</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">loaded</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">gdb</span><span class="o">.</span><span class="n">events</span><span class="o">.</span><span class="n">new_objfile</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">gdb_on_new_objfile</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">unloaded</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">gdb</span><span class="o">.</span><span class="n">events</span><span class="o">.</span><span class="n">new_objfile</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">gdb_on_new_objfile</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">gdb_on_new_objfile</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;[HELLO] Event: new_objfile:&quot;</span><span class="p">,</span> <span class="n">event</span><span class="p">)</span>
</code></pre></div>
<h3 id="urlspy">urls.py</h3>
<p>Includes URL definitions for GDBFrontend REST API. Plugins can define URLs and use them for communicating with each other.</p>
<p>URLs must be defined in a python dict named as <code>urls</code> in the following format:
<div class="highlight"><pre><span></span><code><span class="n">urls</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s2">&quot;example-api&quot;</span><span class="p">:</span> <span class="p">{</span>
        <span class="s2">&quot;url&quot;</span><span class="p">:</span> <span class="s2">&quot;/hello/api&quot;</span><span class="p">,</span>
        <span class="s2">&quot;match&quot;</span><span class="p">:</span> <span class="s2">&quot;^/hello/api&quot;</span><span class="p">,</span>
        <span class="s2">&quot;module&quot;</span><span class="p">:</span> <span class="s2">&quot;plugins.hello.url_modules.api&quot;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></p>
<h3 id="rest-api-modules">Rest API Modules</h3>
<p>Rest API Module URLs must be defined in <code>plugin.urls</code>. Module files are stored in <code>url_modules/</code> directory.</p>
<p>Plugin URL modules can be accessed with the path like <code>plugins.hello.url_modules.[module name]</code> and you must use it for <code>plugin.urls["[plugin name]"]["module"]</code>.</p>
<p>A URL module file includes a function named as <code>run(request, params)</code> and GDBFrontend calls that on HTTP request. A typical URL module like this:
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">import</span> <span class="nn">urllib</span>

<span class="kn">import</span> <span class="nn">api.debug</span>

<span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">params</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">params</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">params</span> <span class="o">=</span> <span class="p">{}</span>

    <span class="n">url_path</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">urlparse</span><span class="p">(</span><span class="n">request</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
    <span class="n">qs_params</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">parse_qs</span><span class="p">(</span><span class="n">url_path</span><span class="o">.</span><span class="n">query</span><span class="p">)</span>

    <span class="n">result_json</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="n">result_json</span><span class="p">[</span><span class="s2">&quot;ok&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>

    <span class="n">result_json</span><span class="p">[</span><span class="s2">&quot;sources&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="n">api</span><span class="o">.</span><span class="n">debug</span><span class="o">.</span><span class="n">getSources</span><span class="p">()</span>

    <span class="n">request</span><span class="o">.</span><span class="n">send_response</span><span class="p">(</span><span class="mi">200</span><span class="p">)</span>
    <span class="n">request</span><span class="o">.</span><span class="n">send_header</span><span class="p">(</span><span class="s2">&quot;Content-Type&quot;</span><span class="p">,</span> <span class="s2">&quot;application/json; charset=utf-8&quot;</span><span class="p">)</span>
    <span class="n">request</span><span class="o">.</span><span class="n">end_headers</span><span class="p">()</span>
    <span class="n">request</span><span class="o">.</span><span class="n">wfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">result_json</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
</code></pre></div></p>
<h2 id="plugin-objects">Plugin Objects</h2>
<p>Plugin objects are exists in <code>plugin.plugins</code> dict as <code>plugin.plugins["[plugin name]"] = plugin</code> and <code>plugin</code> is an instance of your plugin class that inherits <code>GDBFrontendPlugin</code>.</p>
<h3 id="plugin-object-attributes">Plugin Object Attributes</h3>
<ul>
<li><code>plugin.module</code></li>
<li><code>plugin.name</code></li>
<li><code>plugin.is_loaded</code></li>
<li><code>plugin.location</code></li>
<li><code>plugin.config</code></li>
<li><code>plugin.urls</code></li>
</ul>
<h2 id="frontend">Frontend</h2>
<p>Frontend files are stored in the <code>plugins/[plugin name]/frontend/</code> directory. There are three basic directory:
<div class="highlight"><pre><span></span><code>frontend/
    css/
        [plugin name].css
    html/
        [plugin name].html
    js/
        [plugin name].js
</code></pre></div>
Those three files will be included as default:
* <code>html/[plugin_name].html</code> will be included to DOM as default.
* <code>css/[plugin_name].css</code> will be included as default.
* <code>js/[plugin_name].js</code> will be included as default.</p>
<p>Plugin's <code>frontend/</code> directory is also served over <strong>HTTP</strong> and its content will be accessable with a URL like <code>/plugins/[plugin_name]/html/foo.html</code> or <code>/plugins/[plugin_name]/js/bar.js</code>.</p>
<h3 id="gdbfrontend-namespace">GDBFrontend Namespace</h3>
<p>All GDBFrontend stuff are exists in <code>GDBFrontend</code> object in Javascript. An example, you can access version like <code>GDBFrontend.version</code>.</p>
<h3 id="backend-configuration">Backend Configuration</h3>
<p>You can access backend configuration via <code>GDBFrontend.config</code>.</p>
<h2 id="frontend-components">Frontend Components</h2>
<h3 id="root-components">Root Components</h3>
<p>All root components are stored in <code>GDBFrontend.components</code>.</p>
<h3 id="sub-components">Sub Components</h3>
<p>Sub components are stored in <code>component.components</code>.</p>
<h4 id="component-gdbfrontend">Component: <code>gdbFrontend</code></h4>
<p><code>GDBFrontend</code> is the main component at root and it uses another components as sub component. It is accesable with <code>GDBFrontend.components.gdbFrontend</code>.</p>
<p>Sub components of <code>gdbFrontend</code> are accessable via <code>GDBFrontend.components.gdbFrontend.components</code>.</p>
<p>For an example you can get open file tabs like this:
<div class="highlight"><pre><span></span><code><span class="o">&gt;</span> <span class="nx">GDBFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">gdbFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">fileTabs</span><span class="p">.</span><span class="nx">files</span>
<span class="o">&lt;</span> <span class="p">(</span><span class="mf">3</span><span class="p">)</span> <span class="p">[{</span><span class="err">…</span><span class="p">},</span> <span class="p">{</span><span class="err">…</span><span class="p">},</span> <span class="p">{</span><span class="err">…</span><span class="p">}]</span>
</code></pre></div></p>
<p>or getting breakpoints from <code>BreakpointsEditor</code> component instance from <code>GDBFrontend</code> component instance.
<div class="highlight"><pre><span></span><code><span class="o">&gt;</span> <span class="nx">GDBFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">gdbFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">breakpointsEditor</span><span class="p">.</span><span class="nx">breakpoints</span>
<span class="o">&lt;</span> <span class="p">[{</span><span class="err">…</span><span class="p">},</span> <span class="p">{</span><span class="err">…</span><span class="p">}]</span>
</code></pre></div></p>
<p>Let's switch to first file tab:
<div class="highlight"><pre><span></span><code><span class="kd">var</span> <span class="nx">switchTo</span> <span class="o">=</span> <span class="nx">GDBFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">gdbFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">fileTabs</span><span class="p">.</span><span class="nx">files</span><span class="p">[</span><span class="mf">0</span><span class="p">];</span>
<span class="nx">GDBFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">gdbFrontend</span><span class="p">.</span><span class="nx">components</span><span class="p">.</span><span class="nx">fileTabs</span><span class="p">.</span><span class="nx">switchFile</span><span class="p">({</span><span class="nx">file</span><span class="o">:</span> <span class="nx">switchTo</span><span class="p">});</span>
</code></pre></div></p>

              
            </article>
          </div>
        </div>
        
      </main>
      
        <footer class="md-footer">
  
    <nav class="md-footer__inner md-grid" aria-label="Footer">
      
        
        <a href="../makefile-integration/" class="md-footer__link md-footer__link--prev" aria-label="Previous: How to integrate GDBFrontend with your Makefile?" rel="prev">
          <div class="md-footer__button md-icon">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
          </div>
          <div class="md-footer__title">
            <div class="md-ellipsis">
              <span class="md-footer__direction">
                Previous
              </span>
              How to integrate GDBFrontend with your Makefile?
            </div>
          </div>
        </a>
      
      
        
        <a href="../python-c-extension-debugging/" class="md-footer__link md-footer__link--next" aria-label="Next: How to debug a Python C extension with GDBFrontend" rel="next">
          <div class="md-footer__title">
            <div class="md-ellipsis">
              <span class="md-footer__direction">
                Next
              </span>
              How to debug a Python C extension with GDBFrontend
            </div>
          </div>
          <div class="md-footer__button md-icon">
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
          </div>
        </a>
      
    </nav>
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-copyright">
  
    <div class="md-copyright__highlight">
      Copyright &copy; 2019, Oğuzhan Eroğlu
    </div>
  
  
    Made with
    <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
      Material for MkDocs
    </a>
  
</div>
      
        <div class="md-social">
  
    
    
    <a href="https://discord.gg/RyVY9MtB4S" target="_blank" rel="noopener" title="GDBFrontend Discord Community" class="md-social__link">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M524.531 69.836a1.5 1.5 0 0 0-.764-.7A485.065 485.065 0 0 0 404.081 32.03a1.816 1.816 0 0 0-1.923.91 337.461 337.461 0 0 0-14.9 30.6 447.848 447.848 0 0 0-134.426 0 309.541 309.541 0 0 0-15.135-30.6 1.89 1.89 0 0 0-1.924-.91 483.689 483.689 0 0 0-119.688 37.107 1.712 1.712 0 0 0-.788.676C39.068 183.651 18.186 294.69 28.43 404.354a2.016 2.016 0 0 0 .765 1.375 487.666 487.666 0 0 0 146.825 74.189 1.9 1.9 0 0 0 2.063-.676A348.2 348.2 0 0 0 208.12 430.4a1.86 1.86 0 0 0-1.019-2.588 321.173 321.173 0 0 1-45.868-21.853 1.885 1.885 0 0 1-.185-3.126 251.047 251.047 0 0 0 9.109-7.137 1.819 1.819 0 0 1 1.9-.256c96.229 43.917 200.41 43.917 295.5 0a1.812 1.812 0 0 1 1.924.233 234.533 234.533 0 0 0 9.132 7.16 1.884 1.884 0 0 1-.162 3.126 301.407 301.407 0 0 1-45.89 21.83 1.875 1.875 0 0 0-1 2.611 391.055 391.055 0 0 0 30.014 48.815 1.864 1.864 0 0 0 2.063.7A486.048 486.048 0 0 0 610.7 405.729a1.882 1.882 0 0 0 .765-1.352c12.264-126.783-20.532-236.912-86.934-334.541zM222.491 337.58c-28.972 0-52.844-26.587-52.844-59.239s23.409-59.241 52.844-59.241c29.665 0 53.306 26.82 52.843 59.239 0 32.654-23.41 59.241-52.843 59.241zm195.38 0c-28.971 0-52.843-26.587-52.843-59.239s23.409-59.241 52.843-59.241c29.667 0 53.307 26.82 52.844 59.239 0 32.654-23.177 59.241-52.844 59.241z"/></svg>
    </a>
  
    
    
    <a href="https://github.com/rohanrhu/gdb-frontend" target="_blank" rel="noopener" title="GDBFrontend Github Repository" class="md-social__link">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
    </a>
  
</div>
      
    </div>
  </div>
</footer>
      
    </div>
    <div class="md-dialog" data-md-component="dialog">
      <div class="md-dialog__inner md-typeset"></div>
    </div>
    <script id="__config" type="application/json">{"base": "../..", "features": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing", "select.version.title": "Select version"}, "search": "../../assets/javascripts/workers/search.22074ed6.min.js"}</script>
    
    
      <script src="../../assets/javascripts/bundle.960e086b.min.js"></script>
      
    
  </body>
</html>